<template>
  <div class="table-wrapper hp100 flex-column" :class="{'drawer-table-wrapper': drawer}">
    <Selection
      v-if="cselection.length > 0 && showSelectTag && selectName" :data="cselection"
      :selectKey="selectKey"
      :selectName="selectName"
      @clearSelect="clearSelect"
      @closeItem="closeItem">
    </Selection>
    <div class="table" v-if="!cloading">
      <!-- :max-height="tableHeight" -->
      <Table
        :columns="useColumns"
        :data="useData"
        :row-class-name="rowClassName"
        ref="table"
        :max-height="tableHeight"
        @on-select-all="selectItem"
        @on-select="selectItem"
        @on-select-all-cancel="removeItem"
        @on-select-cancel="removeItem"
      >
        <template
          v-for="column in useColumns"
          slot-scope="{ row, index }"
          :slot="column.slot"
        >
          <template v-if="column.type === 'Index'">
            {{ (curPage - 1) * pageSize + index + 1 }}
          </template>
          <template v-else-if="showTooltip(column,row) && column.slot !== 'action'">
            <Tooltip
                :key="column.key"
                :max-width="column.width < 200 ?  400 : Math.min(column.width* 2,800)"
                transfer
                placement="top-start"
                class="ivu-table-cell-tooltip"
                :class="column.renderFun ? 'tooltip-render' : ''"
                :disabled="!showTooltipContent"
            >
                <card-render
                    @mouseenter="(e) => {return handleTooltipIn(e,column.type)}"
                    @mouseleave="handleTooltipOut"
                    :render="column.renderFun"
                    :index="index"
                    :row="row"
                    :column="column"
                    :getCellContent="getCellContent"
                >
                </card-render>
                <template slot="content">
                    <card-render
                        showType="content"
                        :render="column.renderFun"
                        :index="index"
                        :row="row"
                        :column="column"
                        :getCellContent="getCellContent"
                    >
                    </card-render>
                </template>
            </Tooltip>
        </template>
        <template v-else>
            <ActionFold v-if="column.slot === 'action' && column.fold" :column="column" :row="row"></ActionFold>
            <Action v-else-if="column.slot === 'action'" :column="column" :row="row"></Action>
            <card-render
                v-if="!(column.slot === 'action' && !column.renderFun)"
                :render="column.renderFun"
                :index="index"
                :row="row"
                :column="column"
                :key="column.key"
                :getCellContent="getCellContent"
            >
            </card-render>
        </template>
          <!-- <CardCell
            v-else
            :index="index"
            :item="row"
            :column="column"
            :action="column.slot === 'action' ? true : false">
          </CardCell> -->
        </template>
      </Table>
      <div class="flex-center page-wrapper page-xjh" v-if="showPage && hasSetPage">
        <div style="display: flex">
        <Page
          ref="page"
          show-total
          :show-sizer="cShowSizer"
          :total="total"
          :current.sync="curPage"
          :page-size="pageSize"
          @on-change="changePage"
          @on-page-size-change="changePageSize"
          show-elevator
          :page-size-opts="pageSizeOptions"
          transfer
        />
<!--        <div class="pagination__jump">-->
<!--          前往-->
<!--          <Input-->
<!--              :number="true"-->
<!--              v-model.trim="curPage"-->
<!--              placeholder=""-->
<!--              @on-change="changePage1"-->
<!--              style="width: 44px;margin-left:2px; text-align: center;"-->
<!--          />-->
<!--          页</div>-->

        </div>
      </div>
    </div>
    <div v-if="cloading && showDef" style="min-height: 200px" class="hp100">
      <NoData :loading="cloading" :noDataText="noDataText"></NoData>
    </div>
    <Modal v-model="htmlModal.show" :z-index="4000" :width="600" :title="htmlModal.title" footer-hide class-name="fix-height-modal">
      <div v-html="htmlModal.content" style="font-size:14px;" class="html-content ql-editor"></div>
    </Modal>
  </div>
</template>
<script>
import { debounce, showTimeNotSecond } from '@/libs/utils';
import NoData from '@/components/common/no-data';
import CardRender from './cardRender';
import Action from './action';
import ActionFold from "./actionFold.vue";
import Selection from './selection.vue'
import CardCell from './cardCell.vue'
export default {
    name: 'TableList',
    components: { NoData, CardRender, Action, Selection, CardCell,ActionFold },
    provide() {
        return {
            tableRoot: this
        };
    },
    props: {
        data: {
            type: Array,
            default:() => []
        },
        columns: {
            type: Array,
            default: () => []
            // 示例 {
            //     title:'xxx',
            //     key:'sss',
            //     setColor:fun, //颜色
            //     filter:fun, //显示
            //     type:'' //href
            //     tooltip:true/false(显示和详情一致)
            //     slot:''
            //     oplist:[] //slot action
            // }
        },
        page: {
            type: Number,
            default: 1
        },
        size: {
            type: Number
        },
        total: {
            type: Number,
            default: 0
        },
        loading: {
            type: Boolean,
            default: true
        },
        noDataText: {
            type: String,
            default:'暂无数据'
        },
        rowClassName: {
            type: Function
        },
        showPage: {
            type: Boolean,
            default: true
        },
        showDef: {
            type: Boolean,
            default: true
        },
        showSelectTag: {
            //表格上方显示Tag
            type: Boolean,
            default: false
        },
        selectKey: {
            type: String,
            default: 'id'
        },
        selectName: {
            type: [String, Function],
            default: 'name'
        },
        selectType: {
            type: String,
            default: 'text'
        },
        selection: {
            type: Array,
            default: () => []
        },
        maxHeight: {
            type: [String, Number],
            default: 'auto'
        },
        disabled: { //禁用选择
            type: [Boolean,Function],
            default: false,
        },
        drawer:{
          type:Boolean,
          default:false
        },
        showLoading:{
          type:Boolean,
          default:true
        },
        showSizer:{
          type:Boolean,
          default:true
        },
        showIndex:{
          type:Boolean,
          default:false
        },
    },
    data() {
        return {
            showTooltipContent: false, // 鼠标滑过overflow文本时，再检查是否需要显示
            curPage: this.page || 1,
            pageSize: 10, //this.size
            needInit:true,
            debounce,
            cselection:  [].concat(this.selection), //选中的数据
            cloading: false,
            htmlModal:{
                title:'描述',
                show:false,
                content:''
            },
            pageSizeOptions:[10,20],
            tableHeight:this.maxHeight || 'auto'
        };
    },
    computed: {
      useColumns() {
        //  && column.title != '创建时间')
            let columns =  this.columns
                .filter((column) => this.getShow(column))
                .map((column,index) => {
                    let col = Object.assign({}, column);
                    col.title = this.getTitle(col);
                    if(!(col.render || col.type === 'Tag') && !col.tooltip){
                      col.tooltip = true
                    }
                    if(!col.key){col.key = `Key${index}`}
                    if (!col.slot && col.key) {
                        col.slot = col.key;
                    }
                    if (col.type === 'index') {
                        col.type = 'Index';
                        col.slot = 'Index';
                    } else if (col.type === 'html') {
                        col.type = 'Html';
                        if(!(col.fun || (col.on && col.on.click))){
                          col.preFun = this.showHtml;
                        }
                    }
                    if(col.slot !== 'action' && col.type !== 'selection'){
                      delete col.width
                    }
                    if(!col.minWidth && col.type !== 'selection' && col.type !== 'action'){
                      col.minWidth = index === 0 ? 100 : col.title ? Math.max(col.title.length * 14 + 36,100) : 50
                    }
                    if (['createTime','created','updatetime','startTime','endTime'].includes(column.key)) {
                        col.minWidth = 135
                        col.maxWidth = 170
                    }
                    col.align = 'left';
                    col.renderFun = col.render;
                    col.type = col.renderFun ? 'render' : col.type ? col.type : 'normal';
                    delete col.render;
                    return col;
                })
                if(columns.length === 0){
                  return []
                }
                // 统一加一个序号
                let indexNo = columns.findIndex(item => item.type === 'Index');
                let hasIndex = indexNo > -1;
                if(this.showIndex){
                  if(hasIndex){
                    columns[indexNo].title = "序号";
                    columns[indexNo].width = 80
                  }
                  let insertNo = columns[0].type === 'selection' ? 1 : 0
                  !hasIndex && columns.splice(insertNo,0,{
                    type: 'Index',
                    title:'序号',
                    width: 80,
                    // align: 'center',
                    slot :'Index'
                  });
                }else{
                  hasIndex && columns.splice(indexNo,1)
                }
            return columns
        },
        hasSetPage() {
            return Object.keys(this.$options.propsData).includes('page');
        },
        hasSetDisabled(){
            return Object.keys(this.$options.propsData).includes('disabled');
        },
        cShowSizer(){
            return (!!this._events['update:size'] || !!this._events['change-size']) && this.showSizer
        },
        useData(){
          return this.data.filter(item => item).map(item => {
            let selectIds = this.cselection.map((select) => select[this.selectKey]);
            return {
              ...item,
              _checked:selectIds.includes(item[this.selectKey]),
              _disabled:this.getDisabled(item)
            }
          })
        }
    },
    watch: {
        page(val) {
            this.curPage = val;
        },
        size(val){
            this.pageSize = val;
        },
        selection(val,oldVal){
            let csIds = this.cselection.map(item => item[this.selectKey]);
            if(val.length != this.cselection.length || val.some((v, i) => !csIds.includes(v[this.selectKey]))){
                this.initSelect(val);
            }
        },
        loading(val){
          this.cloading = val;
        },
        data:{
          handler(val,oldVal) {
            // console.log('data改变',val,oldVal)
            if(val.length != oldVal.length || val.length === 0 || oldVal.some(item => !val.map(item => item[this.selectKey]).includes(item[this.selectKey]))){
              this.cloading = false;
            }
            // this.data.forEach((item) => {
            //     if(!item){
            //       return
            //     }
            //     let selectIds = this.cselection.map((select) => select[this.selectKey]);
            //     item._checked = selectIds.includes(item[this.selectKey]);
            //     item._disabled = this.getDisabled(item)
            // });
            // let columnIndex = this.useColumns.findIndex(item => item.slot === 'action');
            // let column = this.useColumns.find(item => item.slot === 'action');
            // if(val.length > 0 && column && column.opList){
            //   let opList = column.opList.filter((op) => typeof op.show === 'function' ?  op.show(val[0]) : !op.show);
            //   this.useColumns[columnIndex].width = Math.max(opList.map(op => typeof op.txt === 'function' ?  op.txt(val[0]) : op.txt).reduce((arr,current,index) => {
            //       return [...arr,current]
            //   },[]).join('').length * 12 + (opList.length * 9) + 36,100)
            // }
          },
          deep:true
        }
    },
    updated(){
      this.setTableHeight()
      // if(this.needDealInUpdate){
      //   this.setPagination();
      //   this.needDealInUpdate = false;
      // }
    },
    created() {
      if(this.selection.length > 0){
          this.initSelect(this.selection)
          this.needInit = false
      }
      if(this.data.length == 0 && this.showLoading){
        this.data.length = this.pageSize + 1;
        this.cloading = true;
      }
    },
    mounted() {
      this.init();
      if(this._events['update:size']){ //9.27页面优化改为都不计算每页条数，提供10，20两种pageSize选择
        // this.setPagination();
        // this.debounceResize = debounce(this.setPagination, 1000);
        // window.addEventListener('resize', this.debounceResize);
      }
    },
    beforeDestroy() {
      if(this.resizeObserver){
        this.resizeObserver.unobserve(this.resizeElement);
        this.resizeObserver.disconnect();
      }
      // if(this._events['update:size']){
      //   window.removeEventListener('resize', this.debounceResize);
      // }
    },
    methods: {
        setTableHeight(){
          this.resizeElement = this.$el.getElementsByClassName('table')[0];
          if(this.resizeElement && this.drawer){
            if(!this.objResizeObserver){
              this.objResizeObserver = new ResizeObserver((entries) => {
                // console.log('监控表格高度变化',entries)
                this.tableHeight = Math.floor(entries[0].contentRect.height) - 2 - (this.showPage ? 47 : 0)
              });
              this.objResizeObserver.observe(this.resizeElement);
            }
            this.tableHeight = this.resizeElement.offsetHeight - 2 - (this.showPage ? 47 : 0)
          }
        },
        init(){
          this.curPage = this.page;
          this.$emit('update:size',this.pageSize);
          this.setTableHeight();
        },
        getCellContent(column, row) {
            if (column.filter) {
                let value = column.filter(row[column.key], row);
                return value ? value : value === 0 ? 0 : '-';
            } else if (row[column.key] || row[column.key] === 0 || row[column.key] === false) {
                if (['createTime','created','updatetime','startTime','endTime','submitDate','lastScoreTime'].includes(column.key)) { //column.type === 'showTime'
                    // console.log('time',row[column.key],showTimeNotSecond(row[column.key]))
                    return showTimeNotSecond(row[column.key]);
                } else {
                    return row[column.key];
                }
            } else {
                return '-';
            }
        },
        setPagination(height) {
            let _this = this;
            //40:头部，45:分页\
            // if(this.$el.offsetHeight === 0){
            //   this.needDealInUpdate = true;
            //   return
            // }
            this.needDealInUpdate = false;
            let tableBodyHei;
            if(this.maxHeight && this.maxHeight !='auto'){
              this.tableHeight = this.maxHeight;
              tableBodyHei = this.maxHeight - 38 - 47;
            }else if(this.drawer){ //初始化的时候没有高度
              tableBodyHei = window.innerHeight - 124 - 38 - 47;
            }else{
              this.tableHeight = this.$el.offsetHeight - 47;
              tableBodyHei = this.$el.offsetHeight - 38 - 47;
            }
            let pageSize = Math.max(Math.floor(tableBodyHei / 48), 1);
            // console.log(tableBodyHei,pageSize)
            let usePage = this.curPage,
                maxPage;
            if (this.total > 0) {
                maxPage = Math.ceil(this.total / pageSize);
                usePage = Math.min(this.curPage, maxPage);
            }
            if (pageSize === this.pageSize && this.page === usePage && this.init) {
                return;
            }
            this.pageSize = pageSize;
            this.curPage = usePage;
            this.pageSizeOptions =  [10,20,30,40].includes(this.pageSize) ? [10,20,30,40] : [this.pageSize,10,20,30,40].sort((a,b) => a-b < 0 ? -1 : 1)
            this.$emit('update:page',usePage);
            this.$emit('update:size',pageSize);
            if(this.init && this.total > this.pageSize){
                if(this._events['queryFun']){
                  this.$emit('queryFun');
                }else{
                  this.$emit('change-page',usePage);
                }
            }
            this.init = true;
        },
        changePage1(){
          let pagecount = Math.ceil(this.total / this.pageSize)
          if(!(!isNaN(parseFloat(this.curPage)) && isFinite(this.curPage))){
            this.curPage = 1
          }
          
          if(this.curPage>pagecount){
            this.curPage = pagecount
          }
          if(this.curPage<1){
            this.curPage = 1
          }
            
          this.changePage(this.curPage)
        },
      
      
        changePage(page) {
            if(this.isChangeSize){
              this.isChangeSize = false;
              return
            }
            if(this.showLoading){
              this.data.length = this.pageSize + 1;
              this.cloading = true;
            }
            this.curPage = page;
            this.$emit('update:page', page);
            if(this._events['queryFun']){
              this.$emit('queryFun');
            }else{
              this.$emit('change-page', page);
            }
        },
        changePageSize(size) {
            this.pageSize = size;
            this.$emit('update:size', size);
            let curPage = this.curPage;
            if(curPage !== 1){
              this.isChangeSize = true;
            }
            if(this.total > 0){
              let maxPage = Math.ceil(this.total / size)
              if(maxPage < this.curPage){
                curPage = maxPage
              }
            }
            if(this._events['queryFun']){
              setTimeout(() => {
                this.curPage = curPage;
                this.$emit('update:page',curPage);
                this.$emit('queryFun');
              })
            }else{
              this.$emit('update:page',curPage);
              this.$emit('change-size', size);
            }
        },
        selectItem(selection, row) {
            if (!row) {
                //全选
                selection.forEach((select) => {
                    let selExperIds = this.cselection.map((item) => item[this.selectKey]);
                    if (!selExperIds.includes(select[this.selectKey])) {
                        let index = this.data.findIndex(
                            (item) => item[this.selectKey] == select[this.selectKey]
                        );
                        // if (index != -1) {
                        //     select._checked = true;
                        //     this.data[index]._checked = true;
                        // }
                        this.cselection.push(this.data[index]);
                    }
                });
            } else {
                console.log(row)
                let index = this.data.findIndex(
                    (item) => item[this.selectKey] == row[this.selectKey]
                );
                // if (index != -1) {
                    // row._checked = true;
                    // this.data[index]._checked = true;
                // }
                this.cselection.push(this.data[index]);
            }
            this.$emit('update:selection', this.cselection);
            this.$emit('selection-change', this.cselection);
        },
        removeItem(selection, row) {
            if (!row) {
                //全选
                this.data.forEach((item) => {
                    // item._checked = false;
                    this.delSelectItem(item[this.selectKey]);
                });
            } else {
                // let listExper = this.data.filter(
                //     (item) => item[this.selectKey] == row[this.selectKey]
                // );
                // if (listExper.length > 0) {
                //     listExper[0]._checked = false;
                // }
                this.delSelectItem(row[this.selectKey]);
            }
            this.$emit('update:selection', this.cselection);
            this.$emit('selection-change', this.cselection);
        },
        delSelectItem(id) {
            let delExperIndex = this.cselection.findIndex((items) => items[this.selectKey] === id);
            if (delExperIndex >= 0) {
                this.cselection.splice(delExperIndex, 1);
            }
        },
        //外部关闭
        closeItem(data) {
            // 如果选中才删
            if (!this.cselection.find((item) => item[this.selectKey] === data[this.selectKey])) {
                return;
            }
            let index = this.data.findIndex((item) => item[this.selectKey] == data[this.selectKey]);
            if (index != -1) {
                this.$refs.table.toggleSelect(index);
            } else {
                this.delSelectItem(data[this.selectKey]);
            }
            this.$emit('update:selection', this.cselection);
            this.$emit('selection-change', this.cselection);
        },
        clearSelect() {
            if (this.$refs.table) {
                this.$refs.table.selectAll(false);
            }
            this.cselection = [];
            this.$emit('update:selection', this.cselection);
            this.$emit('selection-change', this.cselection);
        },
        initSelect(selection) {
            let cselection = [].concat(selection);
            this.cselection = [];
            console.log(selection)
            if(cselection.length > 0){
              cselection.forEach((select) => {
                  // let index = this.useData.findIndex(
                  //     (item) => item[this.selectKey] == select[this.selectKey]
                  // );
                  // if (index != -1) {
                  //     this.useData[index]._checked = true;
                  // }
                  this.cselection.push(select);
              });
              // console.log(this.cselection)
              this.$emit('update:selection', this.cselection);
              this.$emit('selection-change', this.cselection);
            }else{
              this.clearSelect()
            }
        },
        getShow(col) {
            return typeof col.show === 'function' ? col.show() : col.show !== false ? true : false;
        },
        getSlectShow(sel) {
            return typeof this.selectName === 'function'
                ? this.selectName(sel)
                : sel[this.selectName];
        },
        getTitle(col){
          return typeof col.title === 'function' ? col.title() : col.title;
        },
        showColContent(column, row) {
            return (
                column.render ||
                column.filter ||
                row[column.key] ||
                row[column.key] === 0 ||
                row[column.key] === false ||
                column.value === 'YorN'
            );
        },
        getDisabled(item){
            return typeof this.disabled === 'function'
                ? this.disabled(item)
                : this.hasSetDisabled ? this.disabled : item._disabled
        },
        showTooltip(column,item) {
          let hasRenderTooltip = column.renderFun && ((''+column.renderFun).indexOf(`Tooltip`) != -1 || (''+column.renderFun).indexOf(`Poptip`) != -1);
          return (column.tooltip || column.type === 'Html') && (this.getCellContent(column,item) != '-' || !hasRenderTooltip);
        },
        handleTooltipIn(e,{type,tooltipKey}) {
            const $content = e.target; //this.$refs.content;
            this.showTooltipContent = (type === 'html' || tooltipKey) ? true : $content.scrollWidth > $content.offsetWidth;
        },
        handleTooltipOut(e) {
            // this.showTooltipContent = false;
        },
        showHtml(val,event,title="描述"){
            if (event.target.nodeName == 'A' && event.target.href) {
              event.preventDefault()
            }
            this.htmlModal.title = title;
            this.htmlModal.show = true;
            this.htmlModal.content = val;
        }
    }
};
</script>
<style scoped>
.table-wrapper {
  flex: auto;
  position: relative;
}
.table-wrapper .table{
  flex: auto;
}
.drawer-table-wrapper .table{
  height: 0;
}
.table-wrapper /deep/ .ivu-tooltip,
.table-wrapper /deep/ .ivu-tooltip-rel {
  display: block;
}
.table-wrapper /deep/ .tooltip-render .ivu-tooltip-rel:only-child {
  white-space: nowrap;
  word-wrap: normal;
  text-overflow: ellipsis;
  overflow: hidden;
}
.table-wrapper .text-ellipsis:not(.ivu-tag) {
  word-break: normal;
  display: block;
  max-width: 100%;
}
.page-wrapper {
  padding-top: 15px;
  /* position: sticky;
  bottom: 0px; */
  background: transparent;
}
.page-wrapper /deep/ .ivu-page{
  width: 100%;
  display: flex;
}
.page-wrapper /deep/ .ivu-page-total{
  margin-right: 10px;
}

/* .text-ellipsis {
  white-space: nowrap;
  word-break: normal;
  text-overflow: ellipsis;
  overflow: hidden;
  display: inline-block;
} */
.tag-wrapper .ivu-tag.ivu-tag-border.ivu-tag-closable .text-ellipsis {
  display: inline-block;
  max-width: calc(100% + 2px);
}
.tag-wrapper .ivu-tag.ivu-tag-border >>> .ivu-icon-ios-close:before {
  position: absolute;
  top: -13px;
  left: -12px;
}
.flex-column{
  display: flex;
  flex-direction: column;
}
.pre-wrap {
  white-space: pre-wrap;
}
.pre{
    white-space: pre;
}
.pre:not(.ivu-tag){
  line-height: 1.5;
  max-height: 1.5em;
}
/* .pointer {
  cursor: pointer;
  color: #1563C2;
} */
.pointer.ivu-tag {
  cursor: pointer !important;
}
.blue-color{
    color:var(--url-color) !important;
}
.not-allowed {
  cursor: not-allowed;
  color: #c5c8ce;
}
.table-wrapper .value img {
  max-height: 20px;
}
.hz-table /deep/ .rank1 td {
  background: linear-gradient(
    to bottom,
    rgb(253, 242, 236),
    rgb(254, 213, 195)
  );
}
.hz-table /deep/ .rank2 td {
  background: linear-gradient(
    to bottom,
    rgb(254, 247, 241),
    rgb(251, 221, 195)
  );
}
.hz-table /deep/ .rank3 td {
  background: linear-gradient(
    to bottom,
    rgb(255, 247, 241),
    rgb(255, 238, 194)
  );
}
.hz-table /deep/ .myRank td {
  color: #2d8cf0;
}
.flex-center {
  display: flex;
  align-items: center;
  /* justify-content: center; */
}
.tag-wrapper {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
.mb10 {
  margin-bottom: 10px;
}
.hp100 {
  height: 100%;
}
.flex {
  display: flex;
}
.flex /deep/ .ivu-page-total{
  margin-right: auto;
}

.page-xjh /deep/ .ivu-page{
  display: -webkit-box;
}
.pagination__jump{
  width: 160px;
  font-size: 14px;
  height: 28px;
  line-height: 28px;

}
.pagination__jump /deep/ .ivu-input{
  text-align: center;
  height: 28px;
  line-height: 28px;
}
/* .html-ellipsis,
.html-ellipsis * {
  color: #2d8cf0 !important;
  font-size: 14px;
}
.html-ellipsis {
  display: inline-block;
}
.html-ellipsis * {
  display: inline !important;
} */
</style>
